//
//  QRCodeScanViewController.m
//  JST
//
//  Created by 蔡正军 on 15/7/13.
//  Copyright (c) 2015年 aniuge. All rights reserved.
//

#import "QRCodeScanViewController.h"
#import "ScanAnimationView.h"
#import "UIAlertView+AFNetworking.h"
#import "QRCodeHTMLViewController.h"
#import <objc/runtime.h>
#import "JSTAdWebViewController.h"
#import "JSTAlertView.h"

@interface QRCodeScanViewController ()<JSTAlertViewDelegate>

@property (nonatomic, strong)       ScanAnimationView *scanAnimationView;
@property (nonatomic, strong)       ZXCapture *capture;
@property (nonatomic)               BOOL isReading;
@property (nonatomic, strong)       NSString *scanStringValue;
@property (nonatomic, strong)       QRCodeService *qrCodeService;

@end

@implementation QRCodeScanViewController

- (void)dealloc
{
    
    [_capture stop];
    _session = nil;
    [_preview removeFromSuperlayer];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"通知失败" object:nil];
    
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        self.view.backgroundColor = [UIColor blackColor];
    }
    return self;
}

#pragma mark-- 网络异常
- (void)starNetWorkNotificationObserver
{
    [[NSNotificationCenter defaultCenter] addObserver: self
                                             selector: @selector(reachabilityChanged:)
                                                 name: @"2332"
                                               object: nil];
}

- (void)reachabilityChanged:(NSNotification *)notification
{
    
}

- (void)viewDidLoad {
    [super viewDidLoad];
    [self addSubViews];
    [self starNetWorkNotificationObserver];

}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    
    [self.navigationController setNavigationBarHidden:YES animated:animated];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    
    [self initCapture_IOS7];
    
    [self.scanAnimationView startScanAnimation];
    [self.scanAnimationView stopLoading];
    
    
    //网络不可用时调用
//    AppDelegate *appdelegate = [UIApplication sharedApplication].delegate;
//    
//    if (![appdelegate isNetReachable]) {
//        
//        [self.scanAnimationView showNetWorkException];
//        [self stopReading];
//        
//        return;
//    }
}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
//    kAppDelegate.tabBarController.tabBar.hidden = NO;
}

- (void)addSubViews
{
    [self.view addSubview:self.scanAnimationView];
    [self.view addSubview:self.cancelButton];
    [self.view addSubview:self.flashlightButton];
    [self.view addSubview:self.photoLibraryButton];
    
}

- (void)initCapture_IOS7
{
    NSString *mediaType = AVMediaTypeVideo;
    
    AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:mediaType];
    if (authStatus == AVAuthorizationStatusNotDetermined)//第一次使用
    {
        [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
            dispatch_async(dispatch_get_main_queue(), ^{
                if (granted) {
                    [self startReading];
                }else{
                    
                    [self showAVAuthorizationTip];
                    [self.navigationController popViewControllerAnimated:YES];
                    
                }
            });
        }];
        
    }else if (authStatus == AVAuthorizationStatusAuthorized) {//用户已授权
        //判断当前设备是否能打开相机
        if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
            [self startReading];
        }else{
            [self showAVAuthorizationTip2];
        }
        
    }else if (authStatus == AVAuthorizationStatusDenied)//用户关闭了权限
    {
        [self showAVAuthorizationTip];
    }else {
        
    }
}

#pragma mark-- Propertys

- (QRCodeService *)qrCodeService
{
    if (!_qrCodeService) {
        _qrCodeService = [[QRCodeService alloc]init];
        _qrCodeService.delegate = self;
    }
    return _qrCodeService;
}

- (ScanAnimationView *)scanAnimationView
{
    if (!_scanAnimationView) {
        _scanAnimationView = [[ScanAnimationView alloc] initWithFrame:self.view.bounds];
    }
    return _scanAnimationView;
}

- (UIButton *)cancelButton
{
    if (!_cancelButton) {
        _cancelButton = [UIButton buttonWithType:UIButtonTypeCustom];
        [_cancelButton setImage:[UIImage imageNamed:@"scan_back_btn"] forState:UIControlStateNormal];
        [_cancelButton setFrame:CGRectMake(20-10 , 40-10, 60, 60)];
        [_cancelButton addTarget:self action:@selector(pressCancelButton:) forControlEvents:UIControlEventTouchUpInside];
    }
    return _cancelButton;
}

- (UIButton *)flashlightButton
{
    if (!_flashlightButton) {
        _flashlightButton = [UIButton buttonWithType:UIButtonTypeCustom];
        [_flashlightButton setImage:[UIImage imageNamed:@"scan_flashlight_nomal"] forState:UIControlStateNormal];
        [_flashlightButton setImage:[UIImage imageNamed:@"scan_flashlight_selected"] forState:UIControlStateSelected];
        [_flashlightButton setFrame:CGRectMake(self.view.width - 20-10 - 40 , 40-10, 60, 60)];
        [_flashlightButton addTarget:self action:@selector(changeFlashLightStatus:) forControlEvents:UIControlEventTouchUpInside];
    }
    return _flashlightButton;
}

- (UIButton *)photoLibraryButton
{
    if (!_photoLibraryButton) {
        _photoLibraryButton = [UIButton buttonWithType:UIButtonTypeCustom];
        [_photoLibraryButton setImage:[UIImage imageNamed:@"scan_blum"] forState:UIControlStateNormal];
        NSInteger topHeight = 10;
        if (self.view.height > 500)
            topHeight = 40;
        if (!IOS7_OR_LATER && self.view.height < 500) {
            topHeight = 0;
        }
        [_photoLibraryButton setFrame:CGRectMake((self.view.width - 60)/2 , self.view.height - 60 - topHeight-10, 60, 60)];
        [_photoLibraryButton addTarget:self action:@selector(pressPhotoLibraryButton:) forControlEvents:UIControlEventTouchUpInside];
        
        UILabel *messageLable = [[UILabel alloc] init];
        messageLable.text  = @"将二维码/条形码放入扫描框内\n自动识别不安全链接，请放心扫码";
        messageLable.numberOfLines = 0;
        messageLable.backgroundColor = [UIColor clearColor];
        messageLable.textAlignment   = NSTextAlignmentCenter;
        messageLable.textColor = [UIColor whiteColor];
        messageLable.font = [UIFont fontWithName:HeitiBold size:13];
        messageLable.frame = CGRectMake(-190/2 + 20 - 5 + 10 ,-60, 190+10, 60);
        
        [_photoLibraryButton addSubview:messageLable];
    }
    return _photoLibraryButton;
}

#pragma mark-- Actions
- (void)changeFlashLightStatus:(UIButton *)sender
{
    Class captureDeviceClass = NSClassFromString(@"AVCaptureDevice");
    if (captureDeviceClass != nil) {
        AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        if ([device hasTorch] && [device hasFlash]){
            
            [device lockForConfiguration:nil];
            if (!sender.selected) {
                [device setTorchMode:AVCaptureTorchModeOn];
                sender.selected = YES;
            } else {
                [device setTorchMode:AVCaptureTorchModeOff];
                sender.selected = NO;
            }
            [device unlockForConfiguration];
        }
    }
}


- (void)pressPhotoLibraryButton:(UIButton *)button
{
    [self stopReading];
    
    UIImagePickerController *picker = [[UIImagePickerController alloc] init];
    if (IOS7_OR_LATER) {
        //picker.navigationBar.tintColor = [UIColor whiteColor];
    }
    picker.delegate = self;
    picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    [self presentViewController:picker animated:YES completion:nil];
}


- (void)pressCancelButton:(UIButton *)button
{
    [self.navigationController popViewControllerAnimated:YES];
}

#pragma mark - UIImagePickerControllerDelegate

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    UIImage *image = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
    [self dismissViewControllerAnimated:YES completion:^{
        [self decodeImage:image];
        [self.scanAnimationView stopScanAnimation];
    }];
}

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
    [self dismissViewControllerAnimated:YES completion:^{
        if (!self.isReading) {
            [self startReading];
        }
    }];
}

#pragma mark - Private Methods

- (NSString *)barcodeFormatToString:(ZXBarcodeFormat)format {
    switch (format) {
        case kBarcodeFormatAztec:
            return @"Aztec";
            
        case kBarcodeFormatCodabar:
            return @"CODABAR";
            
        case kBarcodeFormatCode39:
            return @"Code 39";
            
        case kBarcodeFormatCode93:
            return @"Code 93";
            
        case kBarcodeFormatCode128:
            return @"Code 128";
            
        case kBarcodeFormatDataMatrix:
            return @"Data Matrix";
            
        case kBarcodeFormatEan8:
            return @"EAN-8";
            
        case kBarcodeFormatEan13:
            return @"EAN-13";
            
        case kBarcodeFormatITF:
            return @"ITF";
            
        case kBarcodeFormatPDF417:
            return @"PDF417";
            
        case kBarcodeFormatQRCode:
            return @"QR Code";
            
        case kBarcodeFormatRSS14:
            return @"RSS 14";
            
        case kBarcodeFormatRSSExpanded:
            return @"RSS Expanded";
            
        case kBarcodeFormatUPCA:
            return @"UPCA";
            
        case kBarcodeFormatUPCE:
            return @"UPCE";
            
        case kBarcodeFormatUPCEANExtension:
            return @"UPC/EAN extension";
            
        default:
            return @"Unknown";
    }
}

- (void)decodeImage:(UIImage *)image
{
    [self.scanAnimationView showLoading];
    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        CGImageRef imageToDecode = image.CGImage;
        
        ZXLuminanceSource *source = [[ZXCGImageLuminanceSource alloc] initWithCGImage:imageToDecode];
        ZXBinaryBitmap *bitmap = [ZXBinaryBitmap binaryBitmapWithBinarizer:[ZXHybridBinarizer binarizerWithSource:source]];
        
        NSError *error = nil;
        
//        ZXDecodeHints *hints = [ZXDecodeHints hints];
        
        ZXMultiFormatReader *reader = [ZXMultiFormatReader reader];
//        ZXResult *result = [reader decode:bitmap
//                                    hints:hints
//                                    error:&error];
        
        ZXResult *result = [reader decodeWithState:bitmap error:&error];
        
        
        dispatch_async(dispatch_get_main_queue(), ^{
            if (result)
            {
                [self scanQRCodeDidSuccessWithResult:result.text];
            }
            else
            {
                [self showOtherQrCodeContent:@"照片中未识别到二维码"];
                [self.scanAnimationView stopLoading];
                [self stopReading];
            }
        });
        
    });
}

#pragma mark-  iPhone OS SDK 7.0 以后版本的处理

- (void)setupCamera
{
    if (!_session) {
        _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        
        _input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];
        
        _output = [[AVCaptureMetadataOutput alloc]init];
        [_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
        
        _session = [[AVCaptureSession alloc]init];
        [_session setSessionPreset:AVCaptureSessionPresetHigh];
        if ([_session canAddInput:self.input])
        {
            [_session addInput:self.input];
        }
        
        if ([_session canAddOutput:self.output])
        {
            [_session addOutput:self.output];
        }
        
        // 条码类型 AVMetadataObjectTypeQRCode
        [_output setMetadataObjectTypes:[NSArray arrayWithObjects:AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code, AVMetadataObjectTypeQRCode, nil]];
        
        
        _preview =[AVCaptureVideoPreviewLayer layerWithSession:self.session];
        _preview.videoGravity = AVLayerVideoGravityResizeAspectFill;
        _preview.frame =self.view.bounds;
        [self.view.layer insertSublayer:self.preview atIndex:0];
        
        [_session startRunning];
    }
}

-(void)stopReading{
    [_session stopRunning];
    [self.scanAnimationView stopScanAnimation];
    self.flashlightButton.selected = NO;
    self.isReading = NO;
}

- (void)startReading{
//    if (!IOS7_OR_LATER) {
//        [_capture start];
//        self.isReading = YES;
//    }else{
//        _session = nil;
//        [_preview removeFromSuperlayer];
//        self.isReading = YES;
//        [self setupCamera];
//    }
    _session = nil;
    [_preview removeFromSuperlayer];
    self.isReading = YES;
    [self setupCamera];
    
    [self.scanAnimationView startScanAnimation];
}

-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects
      fromConnection:(AVCaptureConnection *)connection
{
    [self stopReading];
    
    [self scanSuccessSystemSound];
    
    NSString *stringValue;
    if (metadataObjects != nil && [metadataObjects count] > 0) {
        
        AVMetadataMachineReadableCodeObject *metadataObj = [metadataObjects objectAtIndex:0];
        stringValue = metadataObj.stringValue;
        [self scanQRCodeDidSuccessWithResult:stringValue];
    }
}

- (void)captureResult:(ZXCapture *)capture result:(ZXResult *)result {
    if (!result) return;
    
    if (self.isReading) {
        
        [capture stop];
        
        self.isReading = NO;
        
        [self scanQRCodeDidSuccessWithResult:result.text];
        
        [self scanSuccessSystemSound];
        
        [self.scanAnimationView stopScanAnimation];
    }
    
}

- (void)scanSuccessSystemSound
{
//    SystemSoundID soundID;
//    NSString *strSoundFile = [[NSBundle mainBundle] pathForResource:@"scan_qrcode" ofType:@"au"];
//    AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:strSoundFile],&soundID);
//    AudioServicesPlaySystemSound(soundID);
}


#pragma mark-- 扫码成功

- (void)scanQRCodeDidSuccessWithResult:(NSString *)stringValue
{
    
    self.scanStringValue  = stringValue;
    
    DLog(@"扫码成功,内容为%@",self.scanStringValue);
    
//    NSString *text = [NSString string];
    
    if ([stringValue hasPrefix:@"http"])
    {
        [self showSafetyAlertViewWith:stringValue];
        return;
    }
    NSString *messageStr = [NSString stringWithFormat:@"扫描结果为:\n%@\n目前无法识别", stringValue];
    JSTAlertView *advertView = [[JSTAlertView alloc] initWithTitle:@"扫描成功" message:messageStr customView:nil delegate:self cancelButtonTitle:@"返回" otherButtonTitles:@"继续"];
    [advertView setCancelBlock:^{
        [self.navigationController popViewControllerAnimated:YES];
    }];
    [advertView setConfirmBlock:^{
        [self startReading];
    }];
    [advertView show];
    

//    if (self.isFromRefund)
//    {
//        [self sendObject:self.scanStringValue];
//        [self.navigationController popViewControllerAnimated:YES];
//    }
//    else
//    {
//        [self displayOverFlowActivityView];
//        [self.qrCodeService beginGetQRCodeRequest:self.scanStringValue];
//    }
}
    
    

- (void)scanQRCodeDidFaild
{
    DLog(@"扫码失败");

}

#pragma mark --
#pragma mark-- 扫码成功后相关提示信息
- (void)showSafetyAlertViewWith:(NSString *)otherUrl
{
    
    
    NSString *subString ;
    if (otherUrl.length>57) {
        subString = [NSString stringWithFormat:@"%@...",[otherUrl substringToIndex:57]];
    }else {
        subString = otherUrl;
    }
    
    NSString *message = [NSString stringWithFormat:@"可能存在安全风险,是否打开此链接?\n %@",subString];
    
    JSTAlertView *alertView = [[JSTAlertView alloc]initWithTitle:@"提示" message:message customView:nil delegate:nil cancelButtonTitle:@"否" otherButtonTitles:@"是"];

    
    alertView.contentAlignment = NSTextAlignmentLeft;
    [alertView setConfirmBlock:^{
        JSTAdWebViewController *webView = [[JSTAdWebViewController alloc] init];
        webView.urlStr = otherUrl;
        [self.navigationController pushViewController:webView animated:YES];
    }];
    
    [alertView setCancelBlock:^{
        
        //        [self startReading];
        [self.navigationController popViewControllerAnimated:YES];
    }];
    
    [alertView show];
}


- (void)showOtherQrCodeContent:(NSString *)content
{
    JSTAlertView *alertView = [[JSTAlertView alloc]initWithTitle:@"提示" message:content customView:nil delegate:nil cancelButtonTitle:nil otherButtonTitles:@"确定"];

    
    alertView.contentAlignment = NSTextAlignmentCenter;
    [alertView setConfirmBlock:^{
        //        [self startReading];
        [self.navigationController popViewControllerAnimated:YES];
    }];
    
    
    [alertView show];
}//其他非url的内容提示

//相机权限提示
- (void)showAVAuthorizationTip
{
    [self.scanAnimationView stopLoading];
    JSTAlertView *alertView = [[JSTAlertView alloc]initWithTitle:@"未获得相机使用权限" message:@"\n去\"设置>隐私>相机\"开启一下吧" customView:nil delegate:nil cancelButtonTitle:nil otherButtonTitles:@"好"];

    alertView.contentAlignment = NSTextAlignmentCenter;
    [alertView setConfirmBlock:^{
        [self.navigationController popViewControllerAnimated:YES];
    }];
    
    [alertView show];
}//其他非url的内容提示

//相机权限提示
- (void)showAVAuthorizationTip2
{
    [self.scanAnimationView stopLoading];
    
    JSTAlertView *alertView = [[JSTAlertView alloc]initWithTitle:@"未获得相机使用权限" message:@"\n去\"设置>通用>访问限制\"开启一下吧" customView:nil delegate:nil cancelButtonTitle:nil otherButtonTitles:@"好"];
    
    alertView.contentAlignment = NSTextAlignmentCenter;
    [alertView setConfirmBlock:^{
        [self.navigationController popViewControllerAnimated:YES];
    }];
    
    [alertView show];
}//其他非url的内容提示


- (void)getQRCodeInfoResult:(BOOL)isSuccess type:(NSNumber *)type content:(NSString *)content errorMsg:(NSString *)errorMsg
{
    [self removeOverFlowActivityView];
    
    [self.scanAnimationView stopLoading];

    if (isSuccess)
    {
        if ([type isEqualToNumber:[NSNumber numberWithInteger:2]])
        {
            // 处理事件
            
        }
        else
        {
            [self presentSheet:content];
            
            //重新扫描
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [self startReading];
            });
        }
    }
    else
    {
        [self presentSheet:errorMsg];
        //重新扫描
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [self startReading];
        });
    }
}

#pragma mark 回调信息

const char refundKey;

- (void)sendObject:(id)object
{
    void(^block)(id object) = objc_getAssociatedObject(self, &refundKey);
    if (block !=nil)
    {
        block(object);
    }
}

- (void)receiveObject:(void(^)(id object))sendObject
{
    objc_setAssociatedObject(self, &refundKey, sendObject, OBJC_ASSOCIATION_COPY);
}

@end
